package top.blackr.folivora.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置默认自适配CPU
 */
@EnableAsync
@Configuration
public class TaskExecutorConfiguration implements AsyncConfigurer {

    public static final int CPU_NUM = Runtime.getRuntime().availableProcessors();

    @Value("${thread.pool.corePoolSize:}")
    private Integer corePoolSize;

    @Value("${thread.pool.maxPoolSize:}")
    private Integer maxPoolSize;

    @Value("${thread.pool.queueCapacity:}")
    private Integer queueCapacity;

    @Value("${thread.pool.awaitTerminationSeconds:}")
    private Integer awaitTerminationSeconds;

    @Bean
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程大小 默认区 CPU 数量
        taskExecutor.setCorePoolSize(corePoolSize == null ? CPU_NUM : corePoolSize);
        // 最大线程大小 默认区 CPU * 2 数量
        taskExecutor.setMaxPoolSize(maxPoolSize == null ? CPU_NUM * 2 : maxPoolSize);
        // 队列最大容量
        taskExecutor.setQueueCapacity(queueCapacity == null ? 500 : queueCapacity);
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        taskExecutor.setAwaitTerminationSeconds(awaitTerminationSeconds == null ? 60 : awaitTerminationSeconds);
        taskExecutor.setThreadNamePrefix("Folivora-Thread-");
        taskExecutor.initialize();
        return taskExecutor;
    }

}
